#ifndef WAVEFILE_H_
#define WAVEFILE_H_

/**
 * \brief Default initializer which attaches methods to corresponding fields of
 * the object.
 */
#define WAVE_FILE_INITIALIZER {wopen, wclose, toStdout, getNextSection}

/**
 * \brief Size in milliseconds of the buffer.
 */
#define BUFFER_DURATION 100

/**
 * Base type of the module. Represents a wav file. Contains all necessary
 * (header, buffer...) to manipulate a wav file.
 */
typedef struct {
	ErrCode (*open)(void *, const char *);	/*!< Constructor. */
	void (*close)(void *);					/*!< Destructor. */
	void (*toStdout)(void*);
	void *(*getNextSection)(void*);
	char fileTypeBlocID[4];		/*!< Sort of "Magic Number" */
	unsigned char fileSize[4];				/*!< File size minus 8 bytes */
	unsigned int fs;
	char fileFormatID[4]; 
	char formatBlocID[4]; 
	unsigned char blockSize[4]; 
	
	unsigned char audioFormat[2];
	unsigned char nbrCanaux[2]; 
	unsigned char frequence[4]; 
	unsigned int freq;						/*!< Numeric translation of previous field */
	unsigned char bytePerSec[4]; 
	unsigned char bytePerBloc[2]; 
	unsigned char bitsPerSample[2]; 
	unsigned short bytesPerSample;
	
	char dataBlocID[4]; 
	unsigned char dataSize[4];
	char *fileName;
	FILE *file;
	/* buffer size in bytes */
	unsigned int bufferSize;
	/* TODO remplacer par une union pouvant représenter les différentes tailles
	 * d'échantillons possibles. (1, 2 ou 3 octets)
	 */
	void *buffer;
}WaveFile;

/**
 * Sort of constructor for a WaveFile object. Opens the file, allocates
 * memory and reads the header of the wav file. Once became useless, an
 * initialised WaveFile object must be freed by a call to WaveFile.close().
 * @param waveFile Pointer on the structure to initialise.
 * @param Name of the Wav file to initialise.
 * @return Error codes defined in errors.h  
 */
extern ErrCode wopen(void *waveFile, const char fileName[]);

/**
 * Sort of destructor for a WaveFile object. Frees all allocated memory and
 * closes the wav file previously opened.
 * @param waveFile WaveFile object to close.
 */
extern void wclose(void *waveFile);

/**
 * Prints the header content to stdout.
 * @param waveFile WaveFile object we want to print.
 */
extern void toStdout(void *waveFile);

/**
 * Returns a pointer to the next section of data.
 * @param waveFile WaveFile to read.
 * @return Next section of data.
 */
extern void *getNextSection(void *waveFile);

extern short uchar2ToShort(const unsigned char cnbr[2]);


#endif /*WAVEFILE_H_*/
